home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_008 / src / hack.main.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  12KB  |  475 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* hack.main.c version 1.0.1 - some cosmetic changes */
  3.  
  4. #include <stdio.h>
  5. #ifndef AMIGA
  6. #include <signal.h>
  7. #endif
  8. /* #include <errno.h> */
  9. #include "hack.h"
  10.  
  11. extern char *getlogin();
  12. extern char plname[PL_NSIZ], pl_character[PL_CSIZ];
  13. extern char *getenv();
  14.  
  15. int (*afternmv)();
  16.  
  17. int done1();
  18. int hangup();
  19.  
  20. char safelock[] = "safelock";
  21. xchar locknum;            /* max num of players */
  22. char SAVEF[PL_NSIZ + 22] = "Saved Games/";
  23. char perm[] = "perm";
  24. char *hname;      /* name of the game (argv[0] of call) */
  25. char obuf[BUFSIZ];   /* BUFSIZ is defined in stdio.h */
  26.  
  27. extern char *nomovemsg;
  28. extern long wailmsg;
  29.  
  30. main(argc,argv)
  31. int argc;
  32. char *argv[];
  33. {
  34.    int fd;
  35. #ifdef NEWS
  36.     int nonews = 0;
  37. #endif NEWS
  38.    char *dir;
  39.  
  40.    initterm();
  41. #ifdef AMIGA
  42.    if (argc == 0)
  43.     {
  44.     geticon();
  45.     hname = HACKNAME;
  46.     argc = 1;
  47.     }
  48.    else
  49. #endif
  50.    hname = argv[0];
  51.  
  52.    /*
  53.     * See if we must change directory to the playground.
  54.     * (Perhaps hack runs suid and playground is inaccessible
  55.     *  for the player.)
  56.     * The environment variable HACKDIR is overridden by a
  57.     *  -d command line option.
  58.     */
  59.    if ( (dir = getenv("HACKDIR")) == NULL)
  60.     dir = HACKDIR;
  61.  
  62.    if(argc > 1 && !strncmp(argv[1], "-d", 2)) {
  63.       argc--;
  64.       argv++;
  65.       dir = argv[0]+2;
  66.       if(*dir == '=' || *dir == ':') dir++;
  67.       if(!*dir && argc > 1) {
  68.          argc--;
  69.          argv++;
  70.          dir = argv[0];
  71.       }
  72.       if(!*dir)
  73.             error("Flag -d must be followed by a directory name.");
  74.    }
  75.  
  76.    /*
  77.     * Now we know the directory containing 'record' and
  78.     * may do a prscore().
  79.     */
  80.    if(argc > 1 && !strncmp(argv[1], "-s", 2)) {
  81.       if(dir) chdirx(dir);
  82.       prscore(argc, argv);
  83.       hackexit(0);
  84.    }
  85.  
  86.    /*
  87.     * It seems he really wants to play. Find the creation date of
  88.     * this game so as to avoid restoring outdated savefiles.
  89.     */
  90.    gethdate(hname);
  91.  
  92.    /*
  93.     * We cannot do chdir earlier, otherwise gethdate will fail.
  94.     */
  95.    if(dir) chdirx(dir);
  96.  
  97.    /*
  98.     * Who am i? Perhaps we should use $USER instead?
  99.     */
  100. #ifdef AMIGA
  101.    if (!*plname)
  102. #endif
  103.     (void) strncpy(plname, getlogin(), sizeof(plname)-1);
  104.  
  105.    /*
  106.     * Process options.
  107.     */
  108.     initoptions();
  109.    while(argc > 1 && argv[1][0] == '-'){
  110.       argv++;
  111.       argc--;
  112.       switch(argv[0][1]){
  113. #ifdef WIZARD
  114.       case 'w':
  115.          if(!strcmp(getlogin(), WIZARD))
  116.             wizard = TRUE;
  117.          else myprintf("Sorry.\n");
  118.          break;
  119. #endif WIZARD
  120. #ifdef NEWS
  121.         case 'n':
  122.             flags.nonews = TRUE;
  123.             break;
  124. #endif NEWS
  125.       case 'u':
  126.          if(argv[0][2])
  127.            (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
  128.          else if(argc > 1) {
  129.            argc--;
  130.            argv++;
  131.            (void) strncpy(plname, argv[0], sizeof(plname)-1);
  132.          } else
  133.             myprintf("Player name expected after -u\n");
  134.          break;
  135.       default:
  136.          myprintf("Unknown option: %s\n", *argv);
  137.       }
  138.    }
  139.  
  140.    if(argc > 1)
  141.       locknum = atoi(argv[1]);
  142. #ifdef WIZARD
  143.    if(wizard) (void) strcpy(plname, "wizard"); else
  144. #endif WIZARD
  145.    if(!*plname || !strncmp(plname, "player", 4)) askname();
  146. #ifdef AMIGA
  147.    if (!pl_character[0])
  148. #endif
  149.    plnamesuffix();      /* strip suffix from name */
  150.  
  151.    setbuf(stdout,obuf);
  152.     (void) srand(getpid());
  153.    startup();
  154.    cls();
  155. #ifndef AMIGA
  156.    (void) signal(SIGHUP, hangup);
  157. #endif
  158. #ifdef WIZARD
  159.    if(!wizard) {
  160. #endif WIZARD
  161. #ifndef AMIGA
  162.       (void) signal(SIGQUIT,SIG_IGN);
  163.       (void) signal(SIGINT,SIG_IGN);
  164. #endif
  165.       if(locknum)
  166.          lockcheck();
  167.       else
  168.          (void) strcpy(lock,plname);
  169. #ifdef WIZARD
  170.    } else {
  171.       register char *sfoo;
  172.       (void) strcpy(lock,plname);
  173.       if(sfoo = getenv("MAGIC"))
  174.          while(*sfoo) {
  175.             switch(*sfoo++) {
  176.             case 'n': (void) srand(*sfoo++);
  177.                break;
  178.             }
  179.          }
  180.       if(sfoo = getenv("GENOCIDED")){
  181.          if(*sfoo == '!'){
  182.             extern struct permonst mons[PMONCOUNT];
  183.             extern char genocided[], fut_geno[];
  184.             register struct permonst *pm = mons;
  185.             register char *gp = genocided;
  186.  
  187.             while(pm < mons+CMNUM+2){
  188.                if(!index(sfoo, pm->mlet))
  189.                   *gp++ = pm->mlet;
  190.                pm++;
  191.             }
  192.             *gp = 0;
  193.          } else
  194.             (void) strcpy(genocided, sfoo);
  195.          (void) strcpy(fut_geno, genocided);
  196.       }
  197.    }
  198. #endif WIZARD
  199.    u.uhp = 1;   /* prevent RIP on early quits */
  200.    u.ux = FAR;   /* prevent nscr() */
  201.    (void) strcat(SAVEF,plname);
  202.    if((fd = open(SAVEF,0)) >= 0 &&
  203.       (uptodate(fd) || unlink(SAVEF) == 666)) {
  204. #ifndef AMIGA
  205.       (void) signal(SIGINT,done1);
  206. #endif
  207.       myputs("Restoring old save file...");
  208.       (void) myfflush(stdout);
  209.       dorecover(fd);
  210.       flags.move = 0;
  211.    } else {
  212. #ifdef NEWS
  213.     if(!flags.nonews)
  214.         if((fd = open(NEWS,0)) >= 0)
  215.             outnews(fd);
  216. #endif NEWS
  217.       flags.ident = 1;
  218.       init_objects(0);
  219.       u_init();
  220. #ifndef AMIGA
  221.       (void) signal(SIGINT,done1);
  222. #endif
  223.       glo(1);
  224.       mklev();
  225.       u.ux = xupstair;
  226.       u.uy = yupstair;
  227.       (void) inshop();
  228.       setsee();
  229.       flags.botlx = 1;
  230.       makedog();
  231.       seemons();
  232.       docrt();
  233.       pickup();
  234.       read_engr_at(u.ux,u.uy);   /* superfluous ? */
  235.       flags.move = 1;
  236.       flags.cbreak = ON;
  237.       flags.echo = OFF;
  238.    }
  239.    setftty();
  240. #ifdef TRACK
  241.    initrack();
  242. #endif TRACK
  243.    for(;;) {
  244.       if(flags.move) {
  245. #ifdef TRACK
  246.          settrack();
  247. #endif TRACK
  248.          if(moves%2 == 0 ||
  249.            (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) {
  250.             extern struct monst *makemon();
  251.             movemon();
  252.             if(!rn2(70))
  253.                 (void) makemon((struct permonst *)0, 0, 0);
  254.          }
  255.          if(Glib) glibr();
  256.          timeout();
  257.             ++moves;
  258.             if(flags.time) flags.botl = 1;
  259.             if(u.uhp < 1) {
  260.                 pline("You die...");
  261.                 done("died");
  262.                 }
  263.          if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50){
  264.              wailmsg = moves;
  265.              if(u.uhp == 1)
  266.              pline("You hear the wailing of the Banshee...");
  267.              else
  268.              pline("You hear the howling of the CwnAnnwn...");
  269.          }
  270.          if(u.uhp < u.uhpmax) {
  271.             if(u.ulevel > 9) {
  272.                if(Regeneration || !(moves%3)) {
  273.                    flags.botl = 1;
  274.                    u.uhp += rnd((int) u.ulevel-9);
  275.                    if(u.uhp > u.uhpmax)
  276.                   u.uhp = u.uhpmax;
  277.                }
  278.             } else if(Regeneration ||
  279.                (!(moves%(22-u.ulevel*2)))) {
  280.                flags.botl = 1;
  281.                u.uhp++;
  282.             }
  283.          }
  284.          if(Teleportation && !rn2(85)) tele();
  285.          if(Searching && multi >= 0) (void) dosearch();
  286.          gethungry();
  287.          invault();
  288.       }
  289.       if(multi < 0) {
  290.          if(!++multi){
  291.             pline(nomovemsg ? nomovemsg :
  292.                "You can move again.");
  293.             nomovemsg = 0;
  294.             if(afternmv) (*afternmv)();
  295.             afternmv = 0;
  296.          }
  297.       }
  298.       flags.move = 1;
  299.       find_ac();
  300. #ifndef QUEST
  301.       if(!flags.mv || Blind)
  302. #endif QUEST
  303.       {
  304.          seeobjs();
  305.          seemons();
  306.          nscr();
  307.       }
  308.       if(flags.botl || flags.botlx) bot();
  309.       if(multi > 0) {
  310. #ifdef QUEST
  311.          if(flags.run >= 4) finddir();
  312. #endif QUEST
  313.          lookaround();
  314.          if(!multi) {   /* lookaround may clear multi */
  315.             flags.move = 0;
  316.             continue;
  317.          }
  318.          if(flags.mv) {
  319.             if(multi<COLNO && !--multi)
  320.                flags.mv = flags.run = 0;
  321.             domove();
  322.          } else {
  323.             --multi;
  324.             rhack(save_cm);
  325.          }
  326.         } else if(multi == 0)
  327.             rhack((char *) 0);
  328.         if(multi && multi%7 == 0)
  329.             (void) fflush(stdout);
  330.    }
  331. }
  332.  
  333. lockcheck()
  334. {
  335. /*   extern int errno;                         */
  336. /*   register int i, fd;                       */
  337. /*                                             */
  338. /* we ignore QUIT and INT at this point        */
  339. /*    if (link(perm,safelock) == -1)           */
  340. /*        error("Cannot link safelock. (Try again or rm safelock.)");*/
  341. /*                                             */
  342. /*                                             */
  343. /*    for(i = 0; i < locknum; i++) {           */
  344. /*       lock[0]= 'a' + i;                     */
  345. /*       if((fd = open(lock,0)) == -1) {       */
  346. /*          if(errno == ENOENT) goto gotlock;  */  /* no such file */
  347. /*          (void) unlink(safelock);           */
  348. /*          error("Cannot open %s", lock);    */
  349. /*       }                    */
  350. /*       (void) close(fd);            */
  351. /*    }                        */
  352. /*     (void) unlink(safelock);            */
  353. /*   error("Too many hacks running now.");    */
  354. /*    }                    */
  355. /* gotlock:                    */
  356. /*    fd = creat(lock,FMASK);                  */
  357. /*    if(unlink(safelock) == -1) {        */
  358. /*        error("Cannot unlink safelock.");*/
  359. /*    if(fd == -1) {                           */
  360. /*       error("cannot creat lock file.");     */
  361. /*    } else {                                 */
  362. /*       int pid;                              */
  363. /*                                             */
  364. /*       pid = getpid();                       */ 
  365. /*        if(write(fd, (char *) &pid, sizeof(pid)) != sizeof(pid)){ */
  366. /*          error("cannot write lock");        */
  367. /*       }                                     */
  368. /*    if(close(fd) == -1) {            */
  369. /*          error("cannot close lock");        */
  370. /*       }                                     */
  371. /*    }                                        */
  372. }
  373.  
  374. /*VARARGS1*/
  375. error(s,a1,a2,a3,a4) char *s,*a1,*a2,*a3,*a4;
  376.    {
  377.    myprintf("Error: ");
  378.    myprintf(s,a1,a2,a3,a4);
  379.    (void) myputchar('\n');
  380.    hackexit(1);
  381.    }
  382.  
  383. glo(foo)
  384. register int foo;
  385. {
  386.    /* construct the string  xlock.n  */
  387.    register char *tf;
  388.  
  389.    tf = lock;
  390.    while(*tf && *tf!='.') tf++;
  391.    (void) sprintf(tf, ".%d", foo);
  392. }
  393.  
  394. /*
  395.  * plname is filled either by an option (-u Player  or  -uPlayer) or
  396.  * explicitly (-w implies wizard) or by askname.
  397.  * It may still contain a suffix denoting pl_character.
  398.  */
  399. askname(){
  400. register int c,ct;
  401.    myprintf("\nWho are you? ");
  402.    ct = 0;
  403.    (void) myfflush();
  404.    while((c = inchar()) != '\n')
  405.       {
  406.       if (c != '-')
  407.          if (c == 8) { /* backspace */
  408.             if (ct) {
  409.         ct--;
  410.         backsp();
  411.         myputchar(' ');
  412.         backsp();
  413.         myfflush();
  414.         }
  415.         continue;
  416.             }
  417.          else
  418.             if (c < 'A' || (c > 'Z' && c < 'a') || c > 'z') c = '_';
  419.                if (ct < sizeof(plname)-1)
  420.                   {
  421.                   plname[ct++] = c;
  422.                   myprintf("%c", c);
  423.                   }
  424.     (void) myfflush();
  425.       }
  426.    plname[ct] = 0;
  427.    if(ct == 0) askname();
  428. #ifdef QUEST
  429.    else myprintf("Hello %s, welcome to quest!\n", plname);
  430. #else
  431.    else myprintf("Hello %s, welcome to hack!\n", plname);
  432. #endif QUEST
  433. }
  434.  
  435. impossible(){
  436.    pline("Program in disorder - perhaps you'd better Quit");
  437. }
  438.  
  439. #ifdef NEWS
  440. int stopnews;
  441.  
  442. stopnws(){
  443. #ifndef AMIGA
  444.    (void) signal(SIGINT, SIG_IGN);
  445. #endif
  446.    stopnews++;
  447. }
  448.  
  449. outnews(fd) int fd; {
  450. int (*prevsig)();
  451. char ch;
  452. #ifndef AMIGA
  453.    prevsig = signal(SIGINT, stopnws);
  454. #endif
  455.    while(!stopnews && read(fd,&ch,1) == 1)
  456.       (void) myputchar(ch);
  457.    (void) myputchar('\n');
  458.    (void) myfflush(stdout);
  459.    (void) close(fd);
  460. #ifndef AMIGA
  461.    (void) signal(SIGINT, prevsig);
  462. #endif
  463.    /* See whether we will ask TSKCFW: he might have told us already */
  464.    if(!stopnews && pl_character[0])
  465.       getret();
  466. }
  467. #endif NEWS
  468.  
  469. chdirx(dir) char *dir; {
  470.    if(chdir(dir) < 0) {
  471.       perror(dir);
  472.       error("Cannot chdir to %s.", dir);
  473.    }
  474. }
  475.